"""A simple python program to retweet any status updates on Twitter 
that are directed to a specified username (default: AutoEcho). 
The retweets will be generated from the authenticated user's Twitter account,
not the account associated with username (unless username is
changed to the value of the authenticating user's account).

Based on the_shrink.py, by Vivek Halder:
http://blog.vivekhaldar.com/post/2830035130/how-to-write-a-twitter-bot-in-python

Uses the minimalist Python Twitter Tools API wrapper written by Mike Verdone:
http://mike.verdone.ca/twitter/

Modified by Joe McCarthy (@gumption)
- retweeting rather than invoking eliza for a more nuanced response
- added a parameter to store the lastid (id of last message retweeted) in a file, 
    to prevent re-retweeting between invocations
    user can still specify a lastid string on invocation
- added a parameter to specify a target username for retweeting 
    the_shrink only searched for @the_shrinkbot mentions
    autoecho will search for mentions of the specified username
        and will only respond to messages that start with that username
    note that the retweets will be posted to the account of whatever username 
        is currently authenticated (e.g., using "twitter authorize" from command prompt)
        so it is recommended that the username of the authenticated user be used for the -u option
        for example, if a Twitter account @bar posts a status update "@foo please retweet",
        and the user is currently authenticated to Twitter as @foo, and runs
        "python -i autoecho.py -u foo"
        the program will post status updates as @foo,
        retweeting any status updates by anyone (including @foo) starting with "@foo ..."
        e.g., given the example above, it would post "RT @bar please retweet"
        status updates in @AutoEcho and @SelfAggrandizer offer examples
- using OptionParser for handling the larger set of arguments

"""

from twitter.api import Twitter, TwitterError
from twitter.oauth import OAuth, write_token_file, read_token_file
from twitter.oauth_dance import oauth_dance

from optparse import OptionParser

import os
import time
import sys

#JFM: Note that the following are the CONSUMER_KEY and CONSUMER_SECRET associated with
# Mike Verdone's Python Twitter Tools application, in the twitter.cmdline module.
# This application presumes that "twitter authorize" has already been run in a command prompt window.

CONSUMER_KEY='uS6hO2sV6tDKIOeVjhnFnQ'
CONSUMER_SECRET='MEYTOS97VvlHX7K1rwHPEqVpTSqZ71HtvoK4sVuYk'

DEFAULT_USERNAME = 'autoecho'
DEFAULT_AUTH_FILENAME = '.twitter_oauth'
DEFAULT_LASTID_FILENAME = '.twitter_lastid'

if __name__ == '__main__':

    #JFM: using OptionParser - see http://docs.python.org/release/2.6.6/library/optparse.html
    # allowing user to specify a username and/or oauth file, in addition to lastid
    parser = OptionParser()
    parser.add_option('-u', '--username', dest='username')
    parser.add_option('-o', '--oauthfile', dest='oauthfile')
    parser.add_option('-l', '--lastid', dest='lastid')
    (options, args) = parser.parse_args()
    
    home_dir = os.environ.get('HOME', '')
    
    if options.username:
        username = options.username
    else:
        username = DEFAULT_USERNAME
    #JFM: user may or may not use an '@' prefix for the username, but we'll need it for the search
    if username[0] != '@':
        username = '@' + username
    
    if options.oauthfile:
        oauth_filename = options.oauthfile
    else:
        oauth_filename = home_dir + os.sep + DEFAULT_AUTH_FILENAME
    oauth_token, oauth_token_secret = read_token_file(oauth_filename)
    
    if options.lastid:
        lastid = options.lastid
    else:
        #JFM: use a file to store / restore the state of lastid between invocations
        lastid_filename = home_dir + os.sep + DEFAULT_LASTID_FILENAME
        try:
            with open(lastid_filename, 'r') as f:
                lastid = f.readline()
        except IOError:
            lastid = ''

    # We use two twitter clients, one to search (reader), another to post status updates (poster). 
    # reader is initialized to use the search.twitter.com API, 
    # enabling it to make search queries, but nothing else
    reader = Twitter(domain='search.twitter.com')
    reader.uriparts=()

    # poster is initialized to use the Twitter REST API methods
    # it is also authenticated via OAuth credentials,
    # enabling it to use any API methods that require authentication
    # We are only going to use it to post status updates.
    poster = Twitter(
        auth=OAuth(
            oauth_token, oauth_token_secret, CONSUMER_KEY, CONSUMER_SECRET),
        secure=True,
        api_version='1',
        domain='api.twitter.com')

    while True:
        # search for mentions of username
        # results are returned in reverse chronological order
        results = reader.search(q=username, since_id=lastid)['results']
    
        if not results:
            print 'No results this time...'

        # process results in reverse order (i.e., chronological order)
        for result in reversed(results):
            asker = result['from_user']
            msgid = str(result['id'])
            incoming_text = result['text']
            print " <<< " + asker + ": " + incoming_text
            if incoming_text.lower().find(username) != 0:
                print '====> No response (not directed to %s)' % (username,)
            elif (lastid != '') and (long(msgid) <= long(lastid)):
                print '====> No response (%s < %s)' % (msgid, lastid)
            else:
                outgoing_text = 'RT @%s %s (%s)' % \
                                (asker, incoming_text[len(username)+1:], msgid)
                print '====> Resp = %s' % outgoing_text
                try:
                    poster.statuses.update(status=outgoing_text)
                except TwitterError as e:
                    print '*** Twitter returned an error:\n***%s' % e
                else:
                    lastid = msgid
                    print 'Last id replied = ', lastid
                    with open(lastid_filename, 'w') as f:
                        f.write(lastid)

        print 'Now sleeping... \n\n'
        time.sleep(30)
    



